package customview.demo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PorterDuff.Mode;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

/**
 * 基本的View类代表一个全空的100×100像素的正方形。为了改变控件的大小和显示更炫的视觉效果，你需要重写onMeasure和onDraw方法。
 * 在onMeasure方法里，新的View会依据给的边界条件来计算它要占据的高度和宽度。在onDraw方法里，通过在画布上画画来创建视觉界面。
 * 
 * 注意：onMeasure方法中必须调用setMeasuredDimension方法；否则，当父容器尝试放置控件时你的控件会引发一个异常。
 */
public class CreateCustomView extends View {

	Paint datePaint; //画笔,包含了画几何图形、文本等的样式和颜色信息
	Paint bodyPaint;
	
	RectF bodyRectF;
	RectF yearRectF;
	RectF monthRectF;
	RectF dayRectF;
	
	public CreateCustomView(Context context) {
		super(context);
		init();
	}

	public CreateCustomView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}
	
	public CreateCustomView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	  /* 重写onDraw（） */  
    @Override  
    protected void onDraw(Canvas canvas) {  
        super.onDraw(canvas);  
        
        // set canvas background
        canvas.drawColor(Color.WHITE, Mode.ADD);

        canvas.drawRoundRect(bodyRectF, 20, 20, bodyPaint);
        canvas.drawRoundRect(yearRectF, 5, 5, datePaint);
        canvas.drawRoundRect(monthRectF, 5, 5, datePaint);
        canvas.drawRoundRect(dayRectF, 5, 5, datePaint);
    }  

	public void init() {
		
		//initialization body paint
		bodyPaint = new Paint();
		bodyPaint.setARGB(90, 00, 00, 00);
		bodyPaint.setAntiAlias(true);
		bodyPaint.setDither(true);
		bodyPaint.setFilterBitmap(true);
		bodyPaint.setStyle(Style.FILL);
		
		//initialization date paint
		datePaint = new Paint();
		datePaint.setARGB(90, 00, 00, 00);
		datePaint.setAntiAlias(true);
		datePaint.setDither(true);
		datePaint.setStyle(Style.STROKE);
		datePaint.setStrokeWidth(1.5f);
		
		bodyRectF = new  RectF(20, 0, 460, 300);
		yearRectF = new RectF(25, 150, 455, 155);
		monthRectF = new RectF(25, 200, 455, 205);
		dayRectF = new RectF(25, 250, 455, 255);
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	

    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	/**
	 * onMeasure方法在控件的父元素正要放置它的子控件时调用。它会问一个问题，“你想要用多大地方啊？”，然后传入两个参数:widthMeasureSpec
	 * 和heightMeasureSpec。它们指明控件可获得的空间以及关于这个空间描述的元数据。
	 * 注意，调用的本地空方法是来计算高度和宽度的。它们会译解widthHeightSpec和heightMeasureSpec值，并计算出合适的高度和宽度值。
	 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		
	/**
	*	边界参数——widthMeasureSpec和heightMeasureSpec ，效率的原因以整数的方式传入。在它们使用之前，首先要做的是使用MeasureSpec
	*	类的静态方法getMode和getSize来译解;
	*
	*	依据specMode的值，如果是AT_MOST，specSize 代表的是最大可获得的空间；如果是EXACTLY，specSize 代表的是精确的尺寸；如果是UNSPECIFIED
	*	对于控件尺寸来说，没有任何参考意义。//当以EXACT方式标记测量尺寸，父元素会坚持在一个指定的精确尺寸区域放置View。在父元素问子元
	*	素要多大空间时，AT_MOST指示者会说给我最大的范围。在很多情况下，你得到的值都是相同的。
	*
	* 	在两种情况下，你必须绝对的处理这些限制。在一些情况下，它可能会返回超出这些限制的尺寸，在这种情况下，你可以让父元素选择如何对待超
	* 	出的View，使用裁剪还是滚动等技术。
	*/

		int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
		int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
		
		int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
		int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
		
		//定义两个变量保存测量结果, 如果没有指定限制的话，设置默认值大小为500*500
		int widthMeasureResult = 500;
		int heightMeasureResult = 500;
		
		if (widthSpecMode == MeasureSpec.AT_MOST) {
			
			// 在最大的有效空间内计算空间理想的尺寸。如果你的控件填充了整个有效空间返回的外部约束。
			widthMeasureResult = widthSpecSize;
		} else if (widthSpecMode == MeasureSpec.EXACTLY) {

			// 如果你的控件适合放在这个限定的界限内返回该值。
			widthMeasureResult = widthSpecSize;
		}
		
		if (heightSpecMode == MeasureSpec.AT_MOST) {
			heightMeasureResult = heightSpecSize;
		} else if (heightSpecMode == MeasureSpec.EXACTLY) {
			heightMeasureResult = heightSpecSize;
		}
		
		//将测量结果传入setMeasuredDimension
		setMeasuredDimension(widthMeasureResult, heightMeasureResult);
	}
	
	
}
